package uk.co.kevinlockwood.kol.pages;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.HttpURLConnection;
import java.net.URL;
import java.util.ArrayList;
import java.util.List;

import android.content.ContextWrapper;

import uk.co.kevinlockwood.kol.droid.DroidHelpers;
import uk.co.kevinlockwood.kol.droid.G;

public class KoLPageBuilder {
	private ContextWrapper parent;
	private String cookie;
	public KoLPageBuilder(ContextWrapper parent, String cookie) {
		this.parent = parent;
		this.cookie = cookie;
	}

	/**
	 * Takes an empty / old KoLPage and repopulates it from the interwebs
	 * Returns a pointer to the same object you give it, or null if it cannot be populated
	 * @param KoLPage page
	 * @return same KoLPage
	 */
	public <T extends KoLPage> T buildPage(T page) {
		if (page == null) return null;
		List<String> html = new ArrayList<String>();
		URL url = null;
		try {
			String pagename = page.pageName();
			if (pagename == null) {
				url = page.fullUrl();
			} else {
				url = new URL("http://www.kingdomofloathing.com/"+pagename);
			}
			if (url == null) return null;
			HttpURLConnection conn = (HttpURLConnection)url.openConnection();

			// we need to be able to read the redirects in the code
			conn.setInstanceFollowRedirects(page.followRedirects());

			// set the session id in the cookie if we have one
			if (cookie != null) conn.setRequestProperty("Cookie", cookie);
			conn.setRequestProperty("User-Agent", "koldroid-v"+DroidHelpers.getVersion(parent));

			// read all the headers into our map
			for (int i=0; ; i++) {
				String headerName = conn.getHeaderFieldKey(i);
				String headerValue = conn.getHeaderField(i);

				if (headerName == null && headerValue == null) {
					break;
				} else if (headerName == null) {
					DroidHelpers.log("Request for URL [",url.toExternalForm(),"] returns [",headerValue,"] cookie was [",cookie,"]");
				} else {
					Boolean carryon = page.readHeader(headerName.toLowerCase(), headerValue);
					if (Boolean.FALSE == carryon) {
						// this page only wants the headers, so stop here (if null is returned we should continue)
						conn.disconnect();
						return page;
					}
				}
			}

			// read the actual html in
			BufferedReader in = new BufferedReader(new InputStreamReader(conn.getInputStream()), G.HTML_BUFFER_LENGTH);
			String inputLine;
			while ((inputLine = in.readLine()) != null) {
				html.add(inputLine);
			}

			// done
			in.close();
			conn.disconnect();

			// build our page
			page.buildFromHtml(html);
		} catch (IOException ioe) {
			// guess we're not online! darn
			if (url == null) {
				DroidHelpers.log("Request from KoLPage [",page.getClass().getName(),"] failed (no url)");
			} else {
				DroidHelpers.log("Request for URL [",url.toExternalForm(),"] failed");
			}
			CannotGetOnlineException cgoe = new CannotGetOnlineException();
			cgoe.initCause(ioe);
			throw cgoe;
		}
		return page;
	}
}
